60 sfg->SV_1DOF_P_BASIC.resetflag =
true;
63 sfg->SV_3DOF_B_BASIC.resetflag =
true;
66 sfg->SV_3DOF_G_BASIC.resetflag =
true;
69 sfg->SV_3DOF_Y_BASIC.resetflag =
true;
72 sfg->SV_6DOF_GB_BASIC.resetflag =
true;
75 sfg->SV_6DOF_GY_KALMAN.resetflag =
true;
78 sfg->SV_9DOF_GBY_KALMAN.resetflag =
true;
101 if (pthisSV_1DOF_P_BASIC)
111 if (pthisSV_3DOF_G_BASIC)
121 if (pthisSV_3DOF_B_BASIC)
131 if (pthisSV_3DOF_Y_BASIC)
141 if (pthisSV_6DOF_GB_BASIC)
151 if (pthisSV_6DOF_GY_KALMAN)
160 #if F_9DOF_GBY_KALMAN 161 if (pthisSV_9DOF_GBY_KALMAN)
165 pthisGyro, pthisMagCal);
182 if (flpftimesecs > pthisSV->
fdeltat)
185 pthisSV->
flpf = 1.0F;
188 pthisSV->
fLPH = pthisPressure->
fH;
189 pthisSV->
fLPT = pthisPressure->
fT;
198 struct AccelSensor *pthisAccel,
float flpftimesecs)
204 if (flpftimesecs > pthisSV->
fdeltat)
207 pthisSV->
flpf = 1.0F;
210 #if THISCOORDSYSTEM == NED 212 #elif THISCOORDSYSTEM == ANDROID 229 struct MagSensor *pthisMag,
float flpftimesecs)
235 if (flpftimesecs > pthisSV->
fdeltat)
238 pthisSV->
flpf = 1.0F;
241 #if THISCOORDSYSTEM == NED 243 #elif THISCOORDSYSTEM == ANDROID 279 struct MagSensor *pthisMag,
float flpftimesecs)
287 if (flpftimesecs > pthisSV->
fdeltat)
290 pthisSV->
flpf = 1.0F;
293 #if THISCOORDSYSTEM == NED 295 #elif THISCOORDSYSTEM == ANDROID 330 for (i =
CHX; i <=
CHZ; i++)
338 pFlash = (
float *) (CALIBRATION_NVM_ADDR + GYRO_NVM_OFFSET);
339 if (*((
uint32 *) pFlash++) == 0x12345678)
342 for (i =
CHX; i <=
CHZ; i++) pthisSV->
fbPl[i] = *(pFlash++);
347 for (i =
CHX; i <=
CHZ; i++)
351 pthisSV->
fbPl[i] = pthisGyro->
fYs[i];
353 pthisSV->
fbPl[i] = 0.0F;
358 #if THISCOORDSYSTEM == NED 360 #elif THISCOORDSYSTEM == ANDROID 396 for (i =
CHX; i <=
CHZ; i++) {
400 pthisSV->
fVelGl[i] = 0.0F;
401 pthisSV->
fDisGl[i] = 0.0F;
406 pFlash = (
float *) (CALIBRATION_NVM_ADDR + GYRO_NVM_OFFSET);
407 if (*((
uint32*) pFlash++) == 0x12345678) {
409 for (i =
CHX; i <=
CHZ; i++)
410 pthisSV->
fbPl[i] = *(pFlash++);
413 for (i =
CHX; i <=
CHZ; i++) {
415 pthisSV->
fbPl[i] = pthisGyro->
fYs[i];
417 pthisSV->
fbPl[i] = 0.0F;
423 #if THISCOORDSYSTEM == NED 425 pthisMag->
fBc, pthisAccel->
fGc, &ftmp, &ftmp);
426 #elif THISCOORDSYSTEM == ANDROID 428 pthisMag->
fBc, pthisAccel->
fGc, &ftmp, &ftmp);
431 pthisMag->
fBc, pthisAccel->
fGc, &ftmp, &ftmp);
460 pthisSV->
fLPH += pthisSV->
flpf * (pthisPressure->
fH - pthisSV->
fLPH);
461 pthisSV->
fLPT += pthisSV->
flpf * (pthisPressure->
fT - pthisSV->
fLPT);
478 #if THISCOORDSYSTEM == NED 480 #elif THISCOORDSYSTEM == ANDROID 496 #if THISCOORDSYSTEM == NED 500 #elif THISCOORDSYSTEM == ANDROID 527 #if THISCOORDSYSTEM == NED 529 #elif THISCOORDSYSTEM == ANDROID 545 #if THISCOORDSYSTEM == NED 549 #elif THISCOORDSYSTEM == ANDROID 593 #if THISCOORDSYSTEM == NED 596 &(pthisSV->
fRho), &(pthisSV->
fChi));
597 #elif THISCOORDSYSTEM == ANDROID 600 &(pthisSV->
fRho), &(pthisSV->
fChi));
604 &(pthisSV->
fRho), &(pthisSV->
fChi));
613 float ftmp1, ftmp2, ftmp3, ftmp4;
624 #if THISCOORDSYSTEM == NED 626 #elif THISCOORDSYSTEM == ANDROID 642 #if THISCOORDSYSTEM == NED 646 #elif THISCOORDSYSTEM == ANDROID 669 float ftmp3DOF3x1[3];
670 float ftmpA3x3[3][3];
697 for (i =
CHX; i <=
CHZ; i++)
698 pthisSV->
fOmega[i] = (
float) pthisGyro->
iYs[i] *
704 fqMi = pthisSV->
fqPl;
714 for (i =
CHX; i <=
CHZ; i++)
715 ftmpMi3x1[i] = (
float) pthisGyro->
iYsFIFO[j][i] *
734 fmodGc = sqrtf(fabs(pthisAccel->
fGc[
CHX] * pthisAccel->
fGc[
CHX] +
740 ftmp = 1.0F / fmodGc;
741 ftmp3DOF3x1[
CHX] = pthisAccel->
fGc[
CHX] * ftmp;
742 ftmp3DOF3x1[
CHY] = pthisAccel->
fGc[
CHY] * ftmp;
743 ftmp3DOF3x1[
CHZ] = pthisAccel->
fGc[
CHZ] * ftmp;
748 ftmp3DOF3x1[
CHX] = 0.0F;
749 ftmp3DOF3x1[
CHY] = 0.0F;
750 ftmp3DOF3x1[
CHZ] = 1.0F;
754 #if THISCOORDSYSTEM == NED 756 #elif THISCOORDSYSTEM == ANDROID 758 ftmp3DOF3x1[
CHX] = -ftmp3DOF3x1[
CHX];
759 ftmp3DOF3x1[
CHY] = -ftmp3DOF3x1[
CHY];
760 ftmp3DOF3x1[
CHZ] = -ftmp3DOF3x1[
CHZ];
766 ftmpMi3x1[
CHX] = 2.0F * (fqMi.
q1 * fqMi.
q3 - fqMi.
q0 * fqMi.
q2);
767 ftmpMi3x1[
CHY] = 2.0F * (fqMi.
q2 * fqMi.
q3 + fqMi.
q0 * fqMi.
q1);
768 ftmpMi3x1[
CHZ] = 2.0F * (fqMi.
q0 * fqMi.
q0 + fqMi.
q3 * fqMi.
q3) - 1.0F;
771 #if THISCOORDSYSTEM == NED 773 #else // ANDROID and WIN8 775 ftmpMi3x1[
CHX] = -ftmpMi3x1[
CHX];
776 ftmpMi3x1[
CHY] = -ftmpMi3x1[
CHY];
777 ftmpMi3x1[
CHZ] = -ftmpMi3x1[
CHZ];
791 for (i = 0; i < 6; i++)
792 for (j = 0; j < 6; j++) pthisSV->
fQw6x6[i][j] = 0.0F;
836 ftmp = fmodGc - 1.0F;
837 fQvGQa = 3.0F * ftmp * ftmp;
843 for (i = 0; i < 6; i++)
845 for (j = 0; j < 3; j++)
850 for (k = 0; k < 6; k++)
854 if (k == j) fC3x6jk = 1.0F;
858 if ((pthisSV->
fQw6x6[i][k] != 0.0F) && (fC3x6jk != 0.0F))
870 for (i = 0; i < 3; i++)
872 for (j = i; j < 3; j++)
876 ftmpA3x3[i][j] = pthisSV->
fQv;
878 ftmpA3x3[i][j] = 0.0F;
881 for (k = 0; k < 6; k++)
885 if (k == i) fC3x6ik = 1.0F;
889 if ((fC3x6ik != 0.0F) && (pthisSV->
fQwCT6x3[k][j] != 0.0F))
892 ftmpA3x3[i][j] += pthisSV->
fQwCT6x3[k][j];
894 ftmpA3x3[i][j] += fC3x6ik * pthisSV->
fQwCT6x3[k][j];
901 ftmpA3x3[1][0] = ftmpA3x3[0][1];
902 ftmpA3x3[2][0] = ftmpA3x3[0][2];
903 ftmpA3x3[2][1] = ftmpA3x3[1][2];
906 for (i = 0; i < 3; i++) pfRows[i] = ftmpA3x3[i];
913 for (i = 0; i < 6; i++)
915 for (j = 0; j < 3; j++)
917 pthisSV->
fK6x3[i][j] = 0.0F;
918 for (k = 0; k < 3; k++)
920 if ((pthisSV->
fQwCT6x3[i][k] != 0.0F) &&
921 (ftmpA3x3[k][j] != 0.0F))
923 pthisSV->
fK6x3[i][j] += pthisSV->
fQwCT6x3[i][k] * ftmpA3x3[k][j];
932 for (i = 0; i < 6; i++)
934 for (j = 0; j < 3; j++)
936 pthisSV->
fK6x3[i][j] = 0.0F;
943 for (i =
CHX; i <=
CHZ; i++)
952 if (pthisSV->
fK6x3[i][CHZ] != 0.0F)
956 if (pthisSV->
fK6x3[i + 3][
CHX] != 0.0F)
960 if (pthisSV->
fK6x3[i + 3][
CHY] != 0.0F)
962 if (pthisSV->
fK6x3[i + 3][CHZ] != 0.0F)
970 ftmp = ftmpq.
q1 * ftmpq.
q1 + ftmpq.
q2 * ftmpq.
q2 + ftmpq.
q3 * ftmpq.
q3;
976 ftmpq.
q0 = sqrtf(fabsf(1.0F - ftmp));
981 ftmp = 1.0F / sqrtf(ftmp);
998 for (i =
CHX; i <=
CHZ; i++)
1014 #if THISCOORDSYSTEM == NED 1019 #elif THISCOORDSYSTEM == ANDROID 1030 #if THISCOORDSYSTEM == NED 1034 #elif THISCOORDSYSTEM == ANDROID 1045 #if F_9DOF_GBY_KALMAN 1054 float ftmpA6x6[6][6];
1061 float ftmpA3x3[3][3];
1071 float fsinDelta6DOF;
1072 float fcosDelta6DOF;
1098 fqMi = pthisSV->
fqPl;
1104 for (j = 0; j < pthisGyro->
iFIFOCount; j++) {
1123 #if THISCOORDSYSTEM == NED 1124 feCompassNED(fR6DOF, &fDelta6DOF, &fsinDelta6DOF, &fcosDelta6DOF, pthisMag->
fBc, pthisAccel->
fGc, &fmodBc, &fmodGc);
1125 #elif THISCOORDSYSTEM == ANDROID 1126 feCompassAndroid(fR6DOF, &fDelta6DOF, &fsinDelta6DOF, &fcosDelta6DOF, pthisMag->
fBc, pthisAccel->
fGc, &fmodBc, &fmodGc);
1128 feCompassWin8(fR6DOF, &fDelta6DOF, &fsinDelta6DOF, &fcosDelta6DOF, pthisMag->
fBc, pthisAccel->
fGc, &fmodBc, &fmodGc);
1135 ftmp = fmodGc - 1.0F;
1136 fQvGQa = 3.0F * ftmp * ftmp;
1141 ftmp = fmodBc - pthisMagCal->
fB;
1142 fQvBQd = 3.0F * ftmp * ftmp;
1150 fqMi = pthisSV->
fqPl = fq6DOF;
1160 #if THISCOORDSYSTEM == NED 1167 #else // ANDROID and WIN8 (ENU gravity positive) 1185 #if THISCOORDSYSTEM == NED 1186 ftmpA3x1[
CHX] = fR6DOF[
CHX][
CHX] * fcosDelta6DOF + fR6DOF[
CHX][
CHZ] * fsinDelta6DOF;
1187 ftmpA3x1[
CHY] = fR6DOF[
CHY][
CHX] * fcosDelta6DOF + fR6DOF[
CHY][
CHZ] * fsinDelta6DOF;
1188 ftmpA3x1[
CHZ] = fR6DOF[
CHZ][
CHX] * fcosDelta6DOF + fR6DOF[
CHZ][
CHZ] * fsinDelta6DOF;
1192 #else // ANDROID and WIN8 (both ENU coordinate systems) 1193 ftmpA3x1[
CHX] = fR6DOF[
CHX][
CHY] * fcosDelta6DOF - fR6DOF[
CHX][
CHZ] * fsinDelta6DOF;
1194 ftmpA3x1[
CHY] = fR6DOF[
CHY][
CHY] * fcosDelta6DOF - fR6DOF[
CHY][
CHZ] * fsinDelta6DOF;
1195 ftmpA3x1[
CHZ] = fR6DOF[
CHZ][
CHY] * fcosDelta6DOF - fR6DOF[
CHZ][
CHZ] * fsinDelta6DOF;
1212 for (i = 0; i < 9; i++)
1213 for (j = i; j < 9; j++)
1214 pthisSV->
fQw9x9[i][j] = 0.0F;
1248 for (i = 1; i < 9; i++)
1249 for (j = 0; j < i; j++)
1258 for (i = 0; i < 9; i++) {
1259 for (j = 0; j < 6; j++) {
1262 for (k = 0; k < 9; k++) {
1267 if (k == j) fC6x9jk = 1.0F;
1268 if (k == (j + 6)) fC6x9jk = -pthisSV->
fAlphaOver2;
1271 if (k == j) fC6x9jk = 1.0F;
1272 if (k == (j + 3)) fC6x9jk = -pthisSV->
fAlphaOver2;
1276 if ((pthisSV->
fQw9x9[i][k] != 0.0F) && (fC6x9jk != 0.0F)) {
1277 if (fC6x9jk == 1.0F) pthisSV->
fQwCT9x6[i][j] += pthisSV->
fQw9x9[i][k];
1285 for (i = 0; i < 6; i++) {
1286 for (j = i; j < 6; j++) {
1288 if (i == j) ftmpA6x6[i][j] = pthisSV->
fQv6x1[i];
1289 else ftmpA6x6[i][j] = 0.0F;
1291 for (k = 0; k < 9; k++) {
1296 if (k == i) fC6x9ik = 1.0F;
1297 if (k == (i + 6)) fC6x9ik = -pthisSV->
fAlphaOver2;
1300 if (k == i) fC6x9ik = 1.0F;
1301 if (k == (i + 3)) fC6x9ik = -pthisSV->
fAlphaOver2;
1305 if ((fC6x9ik != 0.0F) && (pthisSV->
fQwCT9x6[k][j] != 0.0F)) {
1306 if (fC6x9ik == 1.0F) ftmpA6x6[i][j] += pthisSV->
fQwCT9x6[k][j];
1307 else ftmpA6x6[i][j] += fC6x9ik * pthisSV->
fQwCT9x6[k][j];
1313 for (i = 1; i < 6; i++)
1314 for (j = 0; j < i; j++)
1315 ftmpA6x6[i][j] = ftmpA6x6[j][i];
1318 for (i = 0; i < 6; i++)
1319 pfRows[i] = ftmpA6x6[i];
1325 for (i = 0; i < 9; i++)
1326 for (j = 0; j < 6; j++) {
1327 pthisSV->
fK9x6[i][j] = 0.0F;
1328 for (k = 0; k < 6; k++) {
1329 if ((pthisSV->
fQwCT9x6[i][k] != 0.0F) && (ftmpA6x6[k][j] != 0.0F))
1330 pthisSV->
fK9x6[i][j] += pthisSV->
fQwCT9x6[i][k] * ftmpA6x6[k][j];
1335 for (i = 0; i < 9; i++)
1336 for (j = 0; j < 6; j++)
1337 pthisSV->
fK9x6[i][j] = 0.0F;
1342 for (i =
CHX; i <=
CHZ; i++) {
1344 for (j = 0; j < 6; j++) {
1346 if (pthisSV->
fK9x6[i][j] != 0.0F)
1350 if (pthisSV->
fK9x6[i + 3][j] != 0.0F)
1354 if (pthisSV->
fK9x6[i + 6][j] != 0.0F)
1363 ftmpq.
q0 = sqrtf(fabs(1.0F - ftmpq.
q1 * ftmpq.
q1 - ftmpq.
q2 * ftmpq.
q2 - ftmpq.
q3 * ftmpq.
q3));
1368 fveqRu(fgPl, ftmpA3x3, fgMi, 0);
1374 ftmpq.
q0 = sqrtf(fabs(1.0F - ftmpq.
q1 * ftmpq.
q1 - ftmpq.
q2 * ftmpq.
q2 - ftmpq.
q3 * ftmpq.
q3));
1379 fveqRu(fmPl, ftmpA3x3, fmMi, 0);
1383 #if THISCOORDSYSTEM == NED// gravity vector is +z and accel measurement is +z when flat so don't negate 1385 fmPl, fgPl, &fmodBc, &fmodGc);
1386 #elif THISCOORDSYSTEM == ANDROID // gravity vector is -z and accel measurement is +z when flat so negate 1387 ftmpA3x1[
CHX] = -fgPl[
CHX];
1388 ftmpA3x1[
CHY] = -fgPl[
CHY];
1389 ftmpA3x1[
CHZ] = -fgPl[
CHZ];
1391 fmPl, ftmpA3x1, &fmodBc, &fmodGc);
1392 #else // WIN8// gravity vector is -z and accel measurement is -1g when flat so don't negate 1394 fmPl, fgPl, &fmodBc, &fmodGc);
1402 for (i =
CHX; i <=
CHZ; i++) {
1421 #if THISCOORDSYSTEM == NED 1426 #elif THISCOORDSYSTEM == ANDROID 1439 for (i =
CHX; i <=
CHZ; i++) {
1447 #if THISCOORDSYSTEM == NED 1449 #elif THISCOORDSYSTEM == ANDROID 1457 #endif // #if F_9DOF_GBY_KALMAN float fbPl[3]
gyro offset (deg/s)
#define FMIN_6DOF_GY_BPL
minimum permissible power on gyro offsets (deg/s)
#define FLPFSECS_6DOF_GB_BASIC
float fChiPl
tilt from vertical (deg)
SV_3DOF_Y_BASIC structure is the 3DOF basic gyroscope state vector structure.
float fK9x6[9][6]
kalman filter gain matrix K
float flpf
low pass filter coefficient
void fRun_1DOF_P_BASIC(struct SV_1DOF_P_BASIC *pthisSV, struct PressureSensor *pthisPressure)
float fLPRVec[3]
rotation vector
void fmatrixAeqInvA(float *A[], int8 iColInd[], int8 iRowInd[], int8 iPivot[], int8 isize, int8 *pierror)
function uses Gauss-Jordan elimination to compute the inverse of matrix A in situ on exit...
float fDeltaPl
a posteriori inclination angle from Kalman filter (deg)
Quaternion fq
unfiltered orientation quaternion
void f3DOFMagnetometerMatrixNED(float fR[][3], float fBc[])
Aerospace NED magnetometer 3DOF flat eCompass function, computing rotation matrix fR...
void fRotationMatrixFromQuaternion(float R[][3], const Quaternion *pq)
compute the rotation matrix from an orientation quaternion
void fInitializeFusion(SensorFusionGlobals *sfg)
#define FMIN_9DOF_GBY_BPL
minimum permissible power on gyro offsets (deg/s)
int8_t resetflag
flag to request re-initialization on next pass
float fLPH
low pass filtered height (m)
#define CHY
Used to access Y-channel entries in various data data structures.
float fLPPhi
low pass roll (deg)
void f3DOFTiltNED(float fR[][3], float fGc[])
Aerospace NED accelerometer 3DOF tilt function, computing rotation matrix fR.
float fdeltat
fusion time interval (s)
int32_t loopcounter
counter incrementing each iteration of sensor fusion (typically 25Hz)
float fAlphaQwbOver6
(PI / 180 * fdeltat) * Qwb / 6
float fR[3][3]
unfiltered orientation matrix
float fOmega[3]
virtual gyro angular velocity (deg/s)
void fRun_6DOF_GB_BASIC(struct SV_6DOF_GB_BASIC *pthisSV, struct MagSensor *pthisMag, struct AccelSensor *pthisAccel)
#define FLPFSECS_3DOF_G_BASIC
void f3x3matrixAeqB(float A[][3], float B[][3])
function sets 3x3 matrix A to 3x3 matrix B
#define FQWB_9DOF_GBY_KALMAN
gyro offset random walk units (deg/s)^2
void fAndroidAnglesDegFromRotationMatrix(float R[][3], float *pfPhiDeg, float *pfTheDeg, float *pfPsiDeg, float *pfRhoDeg, float *pfChiDeg)
extract the Android angles in degrees from the Android rotation matrix
float fLPPsi
low pass yaw (deg)
Quaternion fq
unfiltered orientation quaternion
float fDisGl[3]
displacement (m) in global frame
void fRun_9DOF_GBY_KALMAN(struct SV_9DOF_GBY_KALMAN *pthisSV, struct AccelSensor *pthisAccel, struct MagSensor *pthisMag, struct GyroSensor *pthisGyro, struct MagCalibration *pthisMagCal)
Lower level sensor fusion interface.
int32_t systick
systick timer
#define FPIOVER180
degrees to radians conversion = pi / 180
float fdeltat
fusion time interval (s)
float fAlphaSqQvYQwbOver12
(PI / 180 * fdeltat)^2 * (QvY + Qwb) / 12
Functions to convert between various orientation representations.
float fLPRVec[3]
rotation vector
int32_t systick
systick timer
float fQw9x9[9][9]
covariance matrix Qw
float fChi
tilt from vertical (deg)
#define FQVY_6DOF_GY_KALMAN
gyro sensor noise variance units (deg/s)^2
uint8_t iFIFOCount
number of measurements read from FIFO
Quaternion fqPl
a posteriori orientation quaternion
void fRun_3DOF_B_BASIC(struct SV_3DOF_B_BASIC *pthisSV, struct MagSensor *pthisMag)
Quaternion fLPq
low pass filtered orientation quaternion
void fNEDAnglesDegFromRotationMatrix(float R[][3], float *pfPhiDeg, float *pfTheDeg, float *pfPsiDeg, float *pfRhoDeg, float *pfChiDeg)
extract the NED angles in degrees from the NED rotation matrix
float fZErr[3]
measurement error vector
void feCompassAndroid(float fR[][3], float *pfDelta, float *pfsinDelta, float *pfcosDelta, float fBc[], float fGc[], float *pfmodBc, float *pfmodGc)
Android: basic 6DOF e-Compass function, computing rotation matrix fR and magnetic inclination angle f...
float fLPR[3][3]
low pass filtered orientation matrix
The top level fusion structure.
float fLPPhi
low pass roll (deg)
float fdeltat
fusion time interval (s)
float fVelGl[3]
velocity (m/s) in global frame
float fLPRho
low pass compass (deg)
float q3
z vector component
float fLPRho
low pass compass (deg)
int8_t resetflag
flag to request re-initialization on next pass
int8_t resetflag
flag to request re-initialization on next pass
float fAlphaSqOver4
(PI / 180 * fdeltat)^2 / 4
float fRVec[3]
rotation vector
float fLPPsi
low pass yaw (deg)
#define FQVB_9DOF_GBY_KALMAN
magnetometer sensor noise variance units uT^2 defining minimum deviation from geomagnetic sphere...
void fQuaternionFromRotationMatrix(float R[][3], Quaternion *pq)
compute the orientation quaternion from a 3x3 rotation matrix
void fqAeq1(Quaternion *pqA)
set a quaternion to the unit quaternion
This is the 3DOF basic accelerometer state vector structure.
float fbPl[3]
gyro offset (deg/s)
void fLPFOrientationQuaternion(Quaternion *pq, Quaternion *pLPq, float flpf, float fdeltat, float fOmega[])
function low pass filters an orientation quaternion and computes virtual gyro rotation rate ...
void f3DOFMagnetometerMatrixWin8(float fR[][3], float fBc[])
Windows 8 magnetometer 3DOF flat eCompass function, computing rotation matrix fR. ...
The AccelSensor structure stores raw and processed measurements for a 3-axis accelerometer.
float fLPThe
low pass pitch (deg)
void fInit_9DOF_GBY_KALMAN(struct SV_9DOF_GBY_KALMAN *pthisSV, struct AccelSensor *pthisAccel, struct MagSensor *pthisMag, struct GyroSensor *pthisGyro, struct MagCalibration *pthisMagCal)
float fMaxGyroOffsetChange
maximum permissible gyro offset change per iteration (deg/s)
Magnetic Calibration Structure.
#define FQVG_6DOF_GY_KALMAN
accelerometer sensor noise variance units g^2
void fQuaternionFromRotationVectorDeg(Quaternion *pq, const float rvecdeg[], float fscaling)
computes normalized rotation quaternion from a rotation vector (deg)
float fgdeltat
g (m/s2) * fdeltat
float fBc[3]
averaged calibrated measurement (uT)
float fcosDeltaPl
cos(fDeltaPl)
Quaternion fLPq
low pass filtered orientation quaternion
float fLPR[3][3]
low pass filtered orientation matrix
void feCompassWin8(float fR[][3], float *pfDelta, float *pfsinDelta, float *pfcosDelta, float fBc[], float fGc[], float *pfmodBc, float *pfmodGc)
Win8: basic 6DOF e-Compass function, computing rotation matrix fR and magnetic inclination angle fDel...
float fOmega[3]
average angular velocity (deg/s)
The SV_1DOF_P_BASIC structure contains state information for a pressure sensor/altimeter.
This is the 3DOF basic magnetometer state vector structure/.
float fDelta
unfiltered inclination angle (deg)
quaternion structure definition
float fLPR[3][3]
low pass filtered orientation matrix
float fYs[3]
averaged measurement (deg/s)
int8_t resetflag
flag to request re-initialization on next pass
void fInit_3DOF_B_BASIC(struct SV_3DOF_B_BASIC *pthisSV, struct MagSensor *pthisMag, float flpftimesecs)
float fLPChi
low pass tilt from vertical (deg)
int32_t iValidMagCal
solver used: 0 (no calibration) or 4, 7, 10 element
float fLPPsi
low pass yaw (deg)
#define FLPFSECS_3DOF_B_BASIC
The PressureSensor structure stores raw and processed measurements for an altimeter.
float fLPThe
low pass pitch (deg)
float fQw6x6[6][6]
covariance matrix Qw
void fRun_3DOF_Y_BASIC(struct SV_3DOF_Y_BASIC *pthisSV, struct GyroSensor *pthisGyro)
void qAeqBxC(Quaternion *pqA, const Quaternion *pqB, const Quaternion *pqC)
function compute the quaternion product qB * qC
float fR[3][3]
unfiltered orientation matrix
float fOmega[3]
angular velocity (deg/s)
float fR[3][3]
unfiltered orientation matrix
float fbErrPl[3]
gyro offset error (deg/s)
void fInit_6DOF_GB_BASIC(struct SV_6DOF_GB_BASIC *pthisSV, struct AccelSensor *pthisAccel, struct MagSensor *pthisMag, float flpftimesecs)
int32 ARM_systick_elapsed_ticks(int32 start_ticks)
float fLPRVec[3]
rotation vector
float fLPT
low pass filtered temperature (C)
void fveqconjgquq(Quaternion *pfq, float fu[], float fv[])
function computes the rotation quaternion that rotates unit vector u onto unit vector v as v=q*...
Math approximations file.
Quaternion fq
unfiltered orientation quaternion
float fRhoPl
compass (deg)
float fAlphaQwbOver6
(PI / 180 * fdeltat) * Qwb / 6
float fGc[3]
averaged precision calibrated measurement (g)
float fMaxGyroOffsetChange
maximum permissible gyro offset change per iteration (deg/s)
void fInit_1DOF_P_BASIC(struct SV_1DOF_P_BASIC *pthisSV, struct PressureSensor *pthisPressure, float flpftimesecs)
SV_6DOF_GB_BASIC is the 6DOF basic accelerometer and magnetometer state vector structure.
float flpf
low pass filter coefficient
float fAlphaSqOver4
(PI / 180 * fdeltat)^2 / 4
float fsinDeltaPl
sin(fDeltaPl)
float fChiPl
tilt from vertical (deg)
The sensor_fusion.h file implements the top level programming interface.
int16_t iYs[3]
average measurement (counts)
int32_t systick
systick timer
float fRPl[3][3]
a posteriori orientation matrix
float fR[3][3]
unfiltered orientation matrix
int32_t systick
systick timer;
#define FMAX_9DOF_GBY_BPL
float fLPChi
low pass tilt from vertical (deg)
Matrix manipulation functions.
float fdeltat
sensor fusion interval (s)
float fQv6x1[6]
measurement noise covariance matrix leading diagonal
float fdeltat
sensor fusion interval (s)
Provides function prototypes for driver level interfaces.
float fLPThe
low pass pitch (deg)
Quaternion fq
unfiltered orientation quaternion
#define FQVY_9DOF_GBY_KALMAN
gyro sensor noise variance units (deg/s)^2
float fH
most recent unaveraged height (m)
void f3DOFTiltAndroid(float fR[][3], float fGc[])
Android accelerometer 3DOF tilt function computing, rotation matrix fR.
#define FQWB_6DOF_GY_KALMAN
gyro offset random walk units (deg/s)^2
int8_t resetflag
flag to request re-initialization on next pass
int8_t resetflag
flag to request re-initialization on next pass
void fInit_3DOF_Y_BASIC(struct SV_3DOF_Y_BASIC *pthisSV)
float fqgErrPl[3]
gravity vector tilt orientation quaternion error (dimensionless)
int16_t iYsFIFO[GYRO_FIFO_SIZE][3]
FIFO measurements (counts)
int8_t iFirstAccelMagLock
denotes that 9DOF orientation has locked to 6DOF eCompass
void fRun_3DOF_G_BASIC(struct SV_3DOF_G_BASIC *pthisSV, struct AccelSensor *pthisAccel)
#define CHX
Used to access X-channel entries in various data data structures.
float fRVecPl[3]
rotation vector
float fOmega[3]
angular velocity (deg/s)
float fAccGl[3]
linear acceleration (g) in global frame
float fRPl[3][3]
a posteriori orientation matrix
void fveqRu(float fv[], float fR[][3], float fu[], int8 itranspose)
function rotates 3x1 vector u onto 3x1 vector using 3x3 rotation matrix fR. the rotation is applied i...
void fInit_6DOF_GY_KALMAN(struct SV_6DOF_GY_KALMAN *pthisSV, struct AccelSensor *pthisAccel, struct GyroSensor *pthisGyro)
void f3x3matrixAeqI(float A[][3])
function sets the 3x3 matrix A to the identity matrix
float fdeltat
fusion filter sampling interval (s)
float fLPChi
low pass tilt from vertical (deg)
void fInit_3DOF_G_BASIC(struct SV_3DOF_G_BASIC *pthisSV, struct AccelSensor *pthisAccel, float flpftimesecs)
void feCompassNED(float fR[][3], float *pfDelta, float *pfsinDelta, float *pfcosDelta, float fBc[], float fGc[], float *pfmodBc, float *pfmodGc)
NED: basic 6DOF e-Compass function, computing rotation matrix fR and magnetic inclination angle fDelt...
float fOmega[3]
angular velocity (deg/s)
float fAlphaOver2
PI / 180 * fdeltat / 2.
void fqAeqNormqA(Quaternion *pqA)
function normalizes a rotation quaternion and ensures q0 is non-negative
Quaternion fqPl
a posteriori orientation quaternion
float fLPDelta
low pass filtered inclination angle (deg)
Quaternion fLPq
low pass filtered orientation quaternion
float fqgErrPl[3]
gravity vector tilt orientation quaternion error (dimensionless)
float fdeltat
fusion time interval (s)
float fT
most recent unaveraged temperature (C)
float fLPRho
low pass compass (deg)
#define FUSION_HZ
(int) actual rate of fusion algorithm execution and sensor FIFO reads
float fAlphaOver2
PI / 180 * fdeltat / 2.
Defines control sub-system.
The MagSensor structure stores raw and processed measurements for a 3-axis magnetic sensor...
void fRotationVectorDegFromQuaternion(Quaternion *pq, float rvecdeg[])
computes rotation vector (deg) from rotation quaternion
float fZErr[6]
measurement error vector
float fRVecPl[3]
rotation vector
float fRhoPl
compass (deg)
float fB
current geomagnetic field magnitude (uT)
float fQwCT9x6[9][6]
Qw.C^T matrix.
int8_t resetflag
flag to request re-initialization on next pass
float flpf
low pass filter coefficient
void fRun_6DOF_GY_KALMAN(struct SV_6DOF_GY_KALMAN *pthisSV, struct AccelSensor *pthisAccel, struct GyroSensor *pthisGyro)
float fQwCT6x3[6][3]
Qw.C^T matrix.
SensorFusionGlobals sfg
This is the primary sensor fusion data structure.
float fBSq
square of fB (uT^2)
#define FLPFSECS_1DOF_P_BASIC
void f3DOFTiltWin8(float fR[][3], float fGc[])
Windows 8 accelerometer 3DOF tilt function computing, rotation matrix fR.
float q2
y vector component
float fbErrPl[3]
gyro offset error (deg/s)
int32_t systick
systick timer
void qAeqAxB(Quaternion *pqA, const Quaternion *pqB)
function compute the quaternion product qA = qA * qB
float fK6x3[6][3]
kalman filter gain matrix K
float fQv
measurement noise covariance matrix leading diagonal
float fDegPerSecPerCount
deg/s per count
float fLPPhi
low pass roll (deg)
float fOmega[3]
average angular velocity (deg/s)
The GyroSensor structure stores raw and processed measurements for a 3-axis gyroscope.
float flpf
low pass filter coefficient
float q1
x vector component
void fFuseSensors(struct SV_1DOF_P_BASIC *pthisSV_1DOF_P_BASIC, struct SV_3DOF_G_BASIC *pthisSV_3DOF_G_BASIC, struct SV_3DOF_B_BASIC *pthisSV_3DOF_B_BASIC, struct SV_3DOF_Y_BASIC *pthisSV_3DOF_Y_BASIC, struct SV_6DOF_GB_BASIC *pthisSV_6DOF_GB_BASIC, struct SV_6DOF_GY_KALMAN *pthisSV_6DOF_GY_KALMAN, struct SV_9DOF_GBY_KALMAN *pthisSV_9DOF_GBY_KALMAN, struct AccelSensor *pthisAccel, struct MagSensor *pthisMag, struct GyroSensor *pthisGyro, struct PressureSensor *pthisPressure, struct MagCalibration *pthisMagCal)
SV_6DOF_GY_KALMAN is the 6DOF Kalman filter accelerometer and gyroscope state vector structure...
float fqmErrPl[3]
geomagnetic vector tilt orientation quaternion error (dimensionless)
int32_t systick
systick timer
void ARM_systick_start_ticks(int32 *pstart)
SV_9DOF_GBY_KALMAN is the 9DOF Kalman filter accelerometer, magnetometer and gyroscope state vector s...
void f3DOFMagnetometerMatrixAndroid(float fR[][3], float fBc[])
Android magnetometer 3DOF flat eCompass function, computing rotation matrix fR.
#define FQVG_9DOF_GBY_KALMAN
accelerometer sensor noise variance units g^2 defining minimum deviation from 1g sphere ...
float fAlphaSqQvYQwbOver12
(PI / 180 * fdeltat)^2 * (QvY + Qwb) / 12
int32_t systick
systick timer;
float fAccGl[3]
linear acceleration (g) in global frame
void fWin8AnglesDegFromRotationMatrix(float R[][3], float *pfPhiDeg, float *pfTheDeg, float *pfPsiDeg, float *pfRhoDeg, float *pfChiDeg)
extract the Windows 8 angles in degrees from the Windows 8 rotation matrix